import { Uploader as VanUploader } from '@antmjs/vantui';
import { UploaderProps } from '@antmjs/vantui/types/uploader';
import Taro from '@tarojs/taro';
import { isArray } from 'lodash';
import { useEffect, useState } from 'react';
import { uploadFoodImage } from 'src/request';
import { showToast } from 'src/utils/toast';

type FileItem = {
  url: string;
  status: 'uploading' | 'done' | 'failed';
}

type UploadProps = Omit<UploaderProps, 'onAfterRead' | 'onDelete' | 'fileList'> & {
  value?: string[] | string;
  onChange?: (value: string[]) => void;  
}

function Uploader(props: UploadProps) {
  const { value, onChange, ...restProps } = props;
  const [fileList, setFileList] = useState<FileItem[]>(normalizeFileList(value))

  useEffect(() => {
    setFileList(normalizeFileList(value))
  }, [value])

  useEffect(() => {
    if (fileList.length > 0) {
      const _fileList = fileList.filter(file => file.status === 'uploading')
      if (_fileList.length === 0) {
        const _urls = fileList.filter(file => file.status === 'done').map(file => file.url)
        onChange?.(_urls)
      }
    }
  }, [fileList])

  function normalizeFileList(_value) {
    if (!_value) {
      return []
    }
    return (isArray(_value) ? _value : [_value]).map(url => ({
      url,
      status: 'done',
    } as FileItem))
  }

  async function uploadImage(tempFile) {
    try {
      const { tempFilePath } = await Taro.compressImage({
        src: tempFile,
        compressedWidth: 642,
      })
      const imageID = await uploadFoodImage(tempFilePath)
      return imageID
    } catch (err) {
      const msg = err.errMsg || err.message
      if (msg && !msg.includes('cancel')) {
        showToast(msg)
      }
      console.error(err)
    }
  }

  async function handleImageAfterRead(event) {
    console.log(event)
    const { file } = event.detail
    const files = Array.isArray(file) ? file : [file]
    setFileList([
      ...fileList,
      ...files.map(_file => ({
        url: _file.url,
        status: 'uploading',
      } as FileItem))
    ]);
    try {
      const imageIDs = await Promise.all(files.map(_file => uploadImage(_file.url)))
      setFileList([
        ...fileList,
        ...imageIDs.map(imageID => ({
          url: imageID,
          status: 'done',
        } as FileItem))
      ])
    } catch (err) {
      showToast(err.errMsg || err.message || '上传失败')
    }
  }

  function handleImageDelete(event) {
    const { index } = event.detail
    const _fileList = [...fileList]
    _fileList.splice(index, 1)
    setFileList(_fileList)
  }

  return (
    <VanUploader
      {...restProps}
      fileList={fileList}
      onAfterRead={handleImageAfterRead}
      onDelete={handleImageDelete}
    />
  );
}

export {
  Uploader
}
